﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PayexpDAL;
using System.Configuration;
using System.IO;
using Utilities;
using PresentationControls;

namespace Moneymatters
{
    public class Translator
    {

        public static BankAccount ToBankAccountDB(string bankName, string accountNumber, string ifsc, string micrCode, string openingBalance,
                                                  bool isBankAccountActive, BankAccount bankAccount)  
        {
            List<string> validationMessages = new List<string>();

            if (string.IsNullOrEmpty(openingBalance.Trim()))
            {
                validationMessages.Add("Bank opening balance is a mandatory field.");
            }

            if (string.IsNullOrEmpty(accountNumber.Trim()))
            {
                validationMessages.Add("Account number is a mandatory field.");
            }

            NumberFormatInfo nfiForAmount = new NumberFormatInfo(); // just two decimal places
            nfiForAmount.NumberDecimalDigits = 2;
            decimal bankOpeningBalanceDecimal;

            if (bankAccount == null)
            {
                bankAccount = new BankAccount();
                bankAccount.CreatedBy = LoginForm.LoggedInUserName;
                bankAccount.CreatedDate = DateTime.Now;
                bankAccount.UpdatedBy = LoginForm.LoggedInUserName;
                bankAccount.UpdatedDate = DateTime.Now;
                bankAccount.IsActive = true;
            }
            else
            {
                bankAccount.UpdatedBy = LoginForm.LoggedInUserName;
                bankAccount.UpdatedDate = DateTime.Now;
            }

            try
            {
                if (!string.IsNullOrEmpty(openingBalance.Trim()))
                {
                    decimal.TryParse(openingBalance.Trim(),
                                         NumberStyles.AllowDecimalPoint, nfiForAmount,
                                         out bankOpeningBalanceDecimal);

                    if (bankOpeningBalanceDecimal <= 0)
                    {
                        validationMessages.Add("Please enter a valid value in the opening balance field. All amount values should be non-negative and can have only 2 digits after the decimal.");
                    }
                    else if (Utils.CountDecimalPlaces(bankOpeningBalanceDecimal) < 3)
                    {
                        bankAccount.FinancialYearOpeningBalance = bankOpeningBalanceDecimal;
                    }
                    else
                    {
                        validationMessages.Add("Please enter a valid value in the opening balance field. All amount values should be non-negative and can have only 2 digits after the decimal.");
                    }
                }
            }
            catch
            {
                validationMessages.Add("Please enter a valid value in the opening balance field. All amount values should be non-negative and can have only 2 digits after the decimal.");
            }

            if (validationMessages.Count > 0)
            {
                throw new ValidationException(string.Join(" ", validationMessages.ToArray()));
            }

            bankAccount.AccountNumber = accountNumber;
            bankAccount.IFSCCode = ifsc;
            bankAccount.MICRCode = micrCode;
            bankAccount.IsBankAccountActive = isBankAccountActive;

            FinancialStartEnd financialStartEnd = Utils.GetFinancialYearStartEnd(DateTime.Now);
            bankAccount.FinancialYearStart = financialStartEnd.FinancialYearStart;
            bankAccount.FinancialYearEnd = financialStartEnd.FinancialYearEnd;

            return bankAccount;
        }
        
        public static TransactionMaster ToTransactionMasterDB(PanelDetails panelDetails)
        {
            // HEAD IS MANDATORY
            List<string> validationMessages = new List<string>();
            if (panelDetails.SelectedTransactionTypes.Count == 0)
            {
                validationMessages.Add("Please select head details.");
            }
            
            Panel transEntryPanel = panelDetails.PanelWithControls;
            if (transEntryPanel != null)
            {
                TransactionMaster transactionMaster = null;
                if (panelDetails.DataForPersistence != null)
                {
                    transactionMaster = (TransactionMaster)panelDetails.DataForPersistence;
                }
                else
                {
                    transactionMaster = new TransactionMaster();
                }

                transactionMaster.IsActive = !panelDetails.IsDeleted;
                
                // if it is a deletion, no point in doing any further checks
                if (!transactionMaster.IsActive)
                {
                    return transactionMaster;
                }

                // VALID AMOUNT IS MANDATORY
                NumberFormatInfo nfiForAmount = new NumberFormatInfo(); // just two decimal places
                nfiForAmount.NumberDecimalDigits = 2;

                TextBox transactionAmountInINR = (TextBox)transEntryPanel.Controls[3];
                decimal transAmountValue;
                try
                {
                    decimal.TryParse(transactionAmountInINR.Text.Trim(),
                                         NumberStyles.AllowDecimalPoint, nfiForAmount,
                                         out transAmountValue) ;
                    if (transAmountValue <= 0)
                    {
                        validationMessages.Add("Please enter a valid value in the amount field. All amount values should be non-negative and can have only 2 digits after the decimal.");
                    }
                    else if (Utils.CountDecimalPlaces(transAmountValue) < 3)
                    {
                        transactionMaster.TransactionAmount = transAmountValue;
                    }
                    else
                    {
                        validationMessages.Add("Please enter a valid value in the amount field. All amount values should be non-negative and can have only 2 digits after the decimal.");
                    }
                }
                catch
                {
                    validationMessages.Add("Please enter a valid value in the amount field. All amount values should be non-negative and can have only 2 digits after the decimal.");
                }

                // VALID DATE IS MANDATORY
                DateTimePicker transactionDate = (DateTimePicker)transEntryPanel.Controls[0];
                if (transactionDate.Value.Date.CompareTo(DateTime.Today.Date) > 0)
                {
                    validationMessages.Add("Transaction Date cannot be later than today's date. Please correct all such occurences.");
                }
                else
                {
                    transactionMaster.TransactionDate = transactionDate.Value;
                }

                ComboBox head = (ComboBox)transEntryPanel.Controls[1];
                transactionMaster.Head = ((StaticList)((ComboBoxItem)head.SelectedItem).Value).ListItemCode;

                // EXPENSE APPROVERS IS MANDATORY IF NOT SET FOR AUTO APPROVAL AND IF NOT ALREADY AUTO APPROVED
                if (transactionMaster.Head.Equals("head_expense"))
                {
                    CheckBoxComboBox expenseApprovers = (CheckBoxComboBox)transEntryPanel.Controls[5];
                    ListSelectionWrapper<ExpenseApprover> dataSource = (ListSelectionWrapper<ExpenseApprover>)expenseApprovers.DataSource;
                    if (!dataSource.Any(t => t.Selected) && !panelDetails.IsAutoApproved)
                    {
                        validationMessages.Add("Expense Transactions must have at least one approver selected if not set for auto approval.");
                    }
                    else
                    {
                        List<int> expenseApproverIdList = new List<int>();
                        foreach (var item in dataSource.Where(t => t.Selected))
                        {
                            expenseApproverIdList.Add(item.Item.Id);
                        }
                        
                        transactionMaster.ExpenseApproverIdList = expenseApproverIdList.GetSquareBracketedCommaSeparatedString();
                        transactionMaster.IsAutoApproved = false;
                    }
                }

                if (validationMessages.Count > 0)
                {
                    throw new ValidationException(string.Join(" ", validationMessages.ToArray()));
                }

                // transaction mode
                ComboBox transactionMode = (ComboBox)transEntryPanel.Controls[2];
                transactionMaster.TransactionModeValue = ((StaticList)((ComboBoxItem)transactionMode.SelectedItem).Value).ListItemCode;

                // reconcilation
                if (panelDetails.IsReconciled)
                {
                    if (!transactionMaster.BankDate.HasValue)
                    {
                        transactionMaster.BankDate = transactionMaster.TransactionDate;
                    }
                }
                else
                {
                    transactionMaster.BankDate = null;
                }

                // set the receipt voucher prefix
                FinancialStartEnd financialStartEnd = Utils.GetFinancialYearStartEnd(transactionMaster.TransactionDate);
                string financialYearString = "FY" + (financialStartEnd.FinancialYearStart - 2000).ToString() + (financialStartEnd.FinancialYearEnd - 2000).ToString();
                if (transactionMaster.Head.Equals("head_income"))
                {
                    //if(appSettings.ContainsKey(Constants.AppSettingsKeys.ReceiptPrefix))
                    //if (AppSettingsLoader.AppSettingsValuesMap.ContainsKey(Constants.AppSettingsKeys.ReceiptPrefix))
                    if (!string.IsNullOrEmpty(SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ReceiptPrefix)))
                    {
                        //string prefix = appSettings[Constants.AppSettingsKeys.ReceiptPrefix];
                        string prefix = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.ReceiptPrefix);
                        if (!prefix.EndsWith("/"))
                        {
                            prefix = prefix + "/";
                        }

                        prefix = prefix + financialYearString + "/";
                        transactionMaster.VoucherReceiptPrefix = prefix;
                    }
                }
                if (transactionMaster.Head.Equals("head_expense"))
                {
                    //if (appSettings.ContainsKey(Constants.AppSettingsKeys.VoucherPrefix))
                    //if (AppSettingsLoader.AppSettingsValuesMap.ContainsKey(Constants.AppSettingsKeys.VoucherPrefix))
                    if (!string.IsNullOrEmpty(SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.VoucherPrefix)))
                    {
                        //string prefix = appSettings[Constants.AppSettingsKeys.VoucherPrefix];
                        string prefix = SettingsAndStaticListLoader.GetAppSettingValue(Constants.AppSettingsKeys.VoucherPrefix);
                        if (!prefix.EndsWith("/"))
                        {
                            prefix = prefix + "/";
                        }

                        prefix = prefix + financialYearString + "/";
                        transactionMaster.VoucherReceiptPrefix = prefix;
                    }
                }

              

                LinkLabel headDetailsLinkLabel = (LinkLabel)transEntryPanel.Controls[4];
                List<string> temp = new List<string>();
                temp.AddRange(panelDetails.SelectedTransactionTypes.Select(t => t.Id.ToString()));
                for (int i = 0; i < temp.Count; i++)
                {
                    temp[i] = "[" + temp[i] + "]";
                }
                transactionMaster.HeadDetailsHierarchyIdList = string.Join(",", temp.ToArray());
                transactionMaster.HeadDetailsLeafId = panelDetails.SelectedTransactionTypes.Last().Id.ToString();

               
                TextBox invoiceBillNo = (TextBox)transEntryPanel.Controls[6];
                if (!string.IsNullOrEmpty(invoiceBillNo.Text))
                {
                    transactionMaster.InvoiceOrBillNumber = invoiceBillNo.Text.Trim();
                }

                LinkLabel narration = (LinkLabel)transEntryPanel.Controls[7];
                if (narration.Tag != null && !string.IsNullOrEmpty(narration.Tag.ToString()))
                {
                    Guid tempGuid = Guid.Empty;
                    Guid.TryParse(narration.Tag.ToString(), out tempGuid);
                    if (tempGuid.Equals(Guid.Empty))
                    {
                        transactionMaster.Narration = narration.Tag.ToString();
                    }
                }

                // set core properties
                if (panelDetails.IsNew)
                {
                    transactionMaster.CreatedBy = LoginForm.LoggedInUserName;
                    transactionMaster.CreatedDate = DateTime.Now;
                }

                transactionMaster.UpdatedBy = LoginForm.LoggedInUserName;
                transactionMaster.UpdatedDate = DateTime.Now;

                return transactionMaster;
            }
            else
            {
                return null;
            }
        }

        public static TransactionMasterChequeDetail ToTransactionMasterChequeDetailsDB(PanelDetails panelDetails)
        {
            Panel transMasterChequeDetailsPanel = panelDetails.PanelWithControls;
            List<string> validationMessages = new List<string>();
            if (transMasterChequeDetailsPanel != null)
            {
                TransactionMasterChequeDetail transactionMasterChequeDetail = null;
                if (panelDetails.DataForPersistence != null)
                {
                    transactionMasterChequeDetail = (TransactionMasterChequeDetail)panelDetails.DataForPersistence;
                }
                else
                {
                    transactionMasterChequeDetail = new TransactionMasterChequeDetail();
                }

                transactionMasterChequeDetail.IsActive = !panelDetails.IsDeleted;

                TextBox chequeNumber = (TextBox)transMasterChequeDetailsPanel.Controls[0];
                try
                {
                    transactionMasterChequeDetail.ChequeNumber = int.Parse(chequeNumber.Text.Trim());
                }
                catch
                {
                    validationMessages.Add("Please enter a valid value in the cheque number box.");
                }

                // picking the amount before other things since it is needed for validation
                NumberFormatInfo nfiForAmount = new NumberFormatInfo(); // just two decimal places
                nfiForAmount.NumberDecimalDigits = 2;

                TextBox chequeAmount = (TextBox)transMasterChequeDetailsPanel.Controls[3];
                decimal chequeAmountValue;
                try
                {
                    decimal.TryParse(chequeAmount.Text.Trim(),
                                        NumberStyles.AllowDecimalPoint, nfiForAmount,
                                        out chequeAmountValue);

                    if (chequeAmountValue <= 0)
                    {
                        validationMessages.Add("Please enter a valid value in the cheque amount box. All amount values should be non-negative and can have only 2 digits after the decimal.");
                    }
                    else if (Utils.CountDecimalPlaces(chequeAmountValue) < 3)
                    {
                        transactionMasterChequeDetail.ChequeAmount = chequeAmountValue;

                    }
                    else
                    {
                        validationMessages.Add("Please enter a valid value in the cheque amount box. All amount values should be non-negative and can have only 2 digits after the decimal.");
                    }

                    //transactionMasterChequeDetail.ChequeAmount = int.Parse(chequeAmount.Text.Trim());
                }
                catch
                {
                    validationMessages.Add("Please enter a valid value in the cheque amount box. All amount values should be non-negative and can have only 2 digits after the decimal.");
                }

                DateTimePicker chequeDate = (DateTimePicker)transMasterChequeDetailsPanel.Controls[1];
                transactionMasterChequeDetail.ChequeDate = chequeDate.Value;
                //if (chequeDate.Value.CompareTo(DateTime.Today.AddDays(1).AddMilliseconds(-1)) > 0)
                //{
                //    validationMessages.Add("Cheque date cannot be later than today's date.");
                //}
                //else
                //{
                //    transactionMasterChequeDetail.ChequeDate = chequeDate.Value;
                //}
                

                ComboBox chequeStatus = (ComboBox)transMasterChequeDetailsPanel.Controls[2];
                transactionMasterChequeDetail.ChequeStatus = ((StaticList)((ComboBoxItem)chequeStatus.SelectedItem).Value).ListItemCode;

                ComboBox drawnOnBank = (ComboBox)transMasterChequeDetailsPanel.Controls[4];
                transactionMasterChequeDetail.ChequeDrawnOnBank = ((StaticList)((ComboBoxItem)drawnOnBank.SelectedItem).Value).ListItemCode;

                TextBox narration = (TextBox)transMasterChequeDetailsPanel.Controls[5];
                transactionMasterChequeDetail.Narration = narration.Text.Trim();

                if (validationMessages.Count > 0)
                {
                    throw new ValidationException(string.Join(" ", validationMessages.ToArray()));
                }

               

                // create the scanned image file name.
                // only the file name will be generated here. the root folder will be picked from the config
                if (!string.IsNullOrEmpty(panelDetails.SelectedFilePathForSaving) &&
                    !string.IsNullOrEmpty(panelDetails.SelectedDocTypeForSaving))
                {
                    string dateTimeForFileName = DateTime.Now.ToString().Replace("/", "-").Replace(":", "-");
                    string fileExtension = Path.GetExtension(panelDetails.SelectedFilePathForSaving);
                    string fileName = panelDetails.SelectedDocTypeForSaving + "_" + dateTimeForFileName + "_" + fileExtension;
                    transactionMasterChequeDetail.ScannedChequeImagePath = fileName;
                    try
                    {
                        transactionMasterChequeDetail.FileContent = File.ReadAllBytes(panelDetails.SelectedFilePathForSaving);
                    }
                    catch { }
                }

                // set core properties
                if (panelDetails.IsNew)
                {
                    transactionMasterChequeDetail.CreatedBy = LoginForm.LoggedInUserName;
                    transactionMasterChequeDetail.CreatedDate = DateTime.Now;
                }

                transactionMasterChequeDetail.UpdatedBy = LoginForm.LoggedInUserName;
                transactionMasterChequeDetail.UpdatedDate = DateTime.Now;

                return transactionMasterChequeDetail;
            }
            else
            {
                return null;
            }
        }

        //public static List<ApplicationSetting> ToApplicationSettingsDB(string voucherPrefix, string receiptPrefix,
        //                                                        string scannedImageLocation, string exportedFilesLocation,
        //                                                        int maxDateRangeInDays, int rowsPerPage,
        //                                                        string defaultExpenseBankAccount, string defaultIncomeBankAccount)
        //{

        //}
    }
}
